package com.icode.service.impl.order;

import com.icode.core.dto.house.HouseInfoDTO;
import com.icode.core.dto.house.HouseWeekDTO;
import com.icode.core.dto.order.OrderDTO;
import com.icode.core.dto.order.OrderInfoDTO;
import com.icode.core.dto.order.ReFundDTO;
import com.icode.core.dto.user.CityDTO;
import com.icode.core.dto.user.DistrictDTO;
import com.icode.core.dto.user.ProvinceDTO;
import com.icode.core.dto.user.UsersInfoDTO;
import com.icode.core.model.house.*;
import com.icode.core.model.order.Order;
import com.icode.core.model.order.ReFund;
import com.icode.core.model.user.*;
import com.icode.core.shared.JodaTimeUtils;
import com.icode.dao.HouseDao;
import com.icode.dao.OrderDao;
import com.icode.dao.UserDao;
import com.icode.service.order.OrderService;
import com.icode.service.user.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;


/**
 * Created with IntelliJ IDEA.
 * User: xianfei
 * Date: 15-1-20
 * Time: 下午2:19
 * To change this template use File | Settings | File Templates.
 */
@Transactional
@Service("orderService")
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private HouseDao houseDao;
    @Autowired
    private MessageService messageService;


    @Override
    @Transactional
    public Order saveOrUpdateOrder(OrderDTO orderDTO, String houseWeekGuid) {
        Order returnOrder;
        String orderTime = JodaTimeUtils.getTime("yyyy-MM-dd HH:mm:ss");
        User user = userDao.findCustomerByUsername(orderDTO.getPhoneNum());
        Province province = userDao.findProvinceById(orderDTO.getProvince());
        City city = userDao.findCityByCityId(orderDTO.getCity());
        District district = userDao.findDistrictByDistrictID(orderDTO.getDistrict());
        UserInfo findUser = userDao.findUsersInfoByPhoneNum(orderDTO.getPhoneNum());
        HouseWeek houseWeek = houseDao.findByGuid(HouseWeek.class, houseWeekGuid);
        HouseInfo houseInfo = houseWeek.houseInfo();
        if (findUser == null) {
            UserInfo usersInfo = new UserInfo(orderDTO.getRealName(), user, orderDTO.getIDCard(), province, city, district, orderDTO.getArea());
            orderDao.saveOrUpdate(usersInfo);
            Order order = orderDTO.toOrder(orderDTO, houseWeek, houseInfo, usersInfo, orderTime);
            orderDao.saveAndUpdateUserStatus(user);
            orderDao.saveOrUpdate(order);
            returnOrder = order;
        } else {
            Order order = orderDTO.toOrder(orderDTO, houseWeek, houseInfo, findUser, orderTime);
            orderDao.saveAndUpdateUserStatus(user);
            orderDao.saveOrUpdate(order);
            returnOrder = order;
        }
        return returnOrder;
    }


    @Override
    @Transactional
    public OrderDTO createOrder(String houseWeekGuid, String phoneNum) {
        UserInfo usersInfo = userDao.findUsersInfoByPhoneNum(phoneNum);
        User user = userDao.findCustomerByUsername(phoneNum);
        HouseWeek houseWeek = houseDao.findByGuid(HouseWeek.class, houseWeekGuid);
        HouseInfo houseInfo = houseWeek.houseInfo();
        HouseInfoDTO houseInfoDTO = HouseInfoDTO.toDTO(houseInfo);
        HouseWeekDTO houseWeekDTO = HouseWeekDTO.toDTO(houseWeek);
        OrderInfoDTO orderInfoDTO = new OrderInfoDTO(houseWeek.price(), "1", houseWeek.price(), "未支付", JodaTimeUtils.getTime("yyyy-MM-dd HH:mm:ss"), "");
        if (usersInfo == null) {
            OrderDTO orderDTO = new OrderDTO(houseInfoDTO, houseWeekDTO, orderInfoDTO, "", "", phoneNum, "", "", "", "");
            orderDTO.initProvinces(ProvinceDTO.toDTOs(userDao.findProvince()));
            return orderDTO;
        }
        UsersInfoDTO usersInfoDTO = UsersInfoDTO.toDTO(usersInfo);
        OrderDTO orderDTO = new OrderDTO(houseInfoDTO, houseWeekDTO, orderInfoDTO, usersInfoDTO.getRealName(), usersInfoDTO.getIDCard(), phoneNum, usersInfoDTO.getProvince(), usersInfoDTO.getCity(), usersInfoDTO.getDistrict(), usersInfoDTO.getArea());
        orderDTO.initAddress(ProvinceDTO.toDTOs(userDao.findProvince()), CityDTO.toDTOs(userDao.findCityById(usersInfoDTO.getProvince())), DistrictDTO.toDTOs(userDao.findDistrictById(usersInfoDTO.getCity())));
        return orderDTO;
    }

    @Override
    @Transactional
    public List<OrderDTO> findOrderByUsersInfo(String username) {
        if (username.equals("")) {
            return findAllOrder();
        } else {
            List<OrderDTO> orderDTOs = OrderDTO.toDTOs(orderDao.findOrderByUsersInfo(username));
            return orderDTOs;
        }
    }

    @Override
    @Transactional
    public Order findOrderByGuid(String guid) {
        return orderDao.findByGuid(Order.class, guid);
    }

    @Override
    @Transactional
    public List<ReFundDTO> findAllReFund() {
        List<ReFund> reFunds = orderDao.findAll(ReFund.class);
        List<ReFundDTO> reFundDTOs = ReFundDTO.toDTOs(reFunds);
        return reFundDTOs;
    }

    @Override
    @Transactional
    public ReFund findReFundByGuid(String guid) {
        return orderDao.findByGuid(ReFund.class, guid);
    }

    @Override
    @Transactional
    public ReFund findReFundByTradeNo(String batchNo) {
        return orderDao.findReFundByTradeNo(batchNo);
    }

    @Override
    @Transactional
    public List<ReFund> findReFundByOrder(Order order) {
        return orderDao.findReFundByOrder(order);
    }

    @Override
    @Transactional
    public Order findOrderByUsersInfoTime(String username, String orderTime) {
        return orderDao.findOrderByUsersInfoTime(username, orderTime);
    }

    @Override
    @Transactional
    public void deleteOrdersByGuid(String guid) {
        orderDao.deleteOrdersByGuid(guid);
    }

    @Override
    @Transactional
    public void paySuccessOrderByGuid(String guid, String alipayTradeNo) {
        orderDao.paySuccessOrderByGuid(guid, alipayTradeNo);
        OrderDTO orderDTO = OrderDTO.toDTO(orderDao.findByGuid(Order.class, guid));
        messageService.sendPayment(orderDTO);
    }

    @Override
    @Transactional
    public void deleteOrdersByList(String[] guids) {
        orderDao.deleteOrdersByList(guids);
    }

    @Override
    @Transactional
    public void revokeOrderByGuid(String guid) {
        orderDao.changeOrderStatusByGuid(guid, "已失效");
    }

    @Override
    @Scheduled(cron = "0 0 0 * * ?")
    public void revokeOrderAuto() {
        List<Order> orders = orderDao.findAll(Order.class);
        for (Order o : orders) {
            if (JodaTimeUtils.isTimeOut(o.orderInfo().time())) {
                orderDao.changeOrderStatusByGuid(o.guid(), "已失效");
            }
        }
    }

    @Override
    @Transactional
    public void addReFund(ReFund reFund) {
        orderDao.saveOrUpdate(reFund);
    }

    @Override
    @Transactional
    public void changeOrderStatusByGuid(String guid, String status) {
        orderDao.changeOrderStatusByGuid(guid, status);
    }

    @Override
    @Transactional
    public void changeReFundStatusByGuid(String guid, String status) {
        orderDao.changeReFundStatusByGuid(guid, status);
    }

    @Override
    @Transactional
    public List<ReFundDTO> findRefundByStatus(String status) {
        List<ReFund> refunds = orderDao.findRefundByStatus(status);
        List<ReFundDTO> reFundDTOs = new ArrayList<>();
        if (!refunds.isEmpty()) {
            reFundDTOs = ReFundDTO.toDTOs(refunds);
            return reFundDTOs;
        }
        return reFundDTOs;
    }

    @Override
    @Transactional
    public void initMyHouse(String orderGuid) {
        Order order = orderDao.findByGuid(Order.class, orderGuid);
        MyHouse myHouse = new MyHouse(order.houseInfo(), order.houseWeek(), order.userInfo(),
                String.valueOf(order.orderInfo().num()), MyHouseStatus.ACTIVITY);

        orderDao.saveOrUpdate(myHouse);
    }

    @Override
    @Transactional
    public List<OrderDTO> findAllOrder() {
        List<Order> orders = orderDao.findAll(Order.class);
        List<OrderDTO> orderDTOs = OrderDTO.toDTOs(orders);
        return orderDTOs;
    }

    @Override
    @Transactional
    public List<OrderDTO> findAllOrderByPage(String currentPage) {
        List<Order> orders = orderDao.findAllOrderByPage(currentPage);
        List<OrderDTO> orderDTOs = OrderDTO.toDTOs(orders);
        return orderDTOs;
    }
}
